package com.ibeeking.found.msg.rest.service.impl;

import com.ibeeking.found.common.base.BaseDO;
import com.ibeeking.found.common.enums.sms.SmsVendorEnum;
import com.ibeeking.found.msg.rest.service.*;
import com.ibeeking.found.msg.service.common.bo.*;
import com.ibeeking.found.msg.service.common.constants.RedisKeyConstant;
import com.ibeeking.found.msg.service.common.dos.MsgTypeDO;
import com.ibeeking.found.msg.service.common.param.SmsTypeParam;
import com.ibeeking.found.msg.service.common.query.MsgTypePageQuery;
import com.ibeeking.found.msg.service.common.vo.MsgTypePageVO;
import com.ibeeking.found.msg.service.common.vo.MsgTypeVO;
import com.ibeeking.found.msg.service.mapper.MsgTypeMapper;
import com.ibeeking.nematos.core.utils.SpringBeanUtil;
import com.ibeeking.nematos.exception.BusinessException;
import com.ibeeking.nematos.redis.annotation.CacheEvict;
import com.ibeeking.nematos.redis.annotation.CacheQuery;
import com.ibeeking.nematos.redis.utils.RedisUtils;
import com.ibeeking.nematos.utils.bean.BeanUtil;
import com.ibeeking.nematos.utils.data.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;

/**
 * @ClassName MsgTypeServiceImpl
 * @Description
 * @Author ibeeking
 * @Date 2020-12-09 10:53
 **/
@Service
public class MsgTypeServiceImpl extends ServiceImpl<MsgTypeMapper, MsgTypeDO> implements IMsgTypeService {

    @Resource
    private MsgTypeMapper msgTypeMapper;
    @Resource
    private RedisUtils redisUtils;
    @Resource
    private ISmsRelationService smsRelationServiceImpl;
    @Resource
    private ISmsConfigService smsConfigServiceImpl;
    @Resource
    private ISmsConfigSignService smsConfigSignServiceImpl;
    @Resource
    private ISmsTemplateService smsTemplateServiceImpl;

    @Override
    public Page<MsgTypePageVO> pageList(MsgTypePageQuery msgTypePageQuery) {
        LambdaQueryWrapper<MsgTypeDO> queryWrapper = new LambdaQueryWrapper<>(MsgTypeDO.class);
        queryWrapper.orderByDesc(BaseDO::getCreateTime);

        if (null != msgTypePageQuery.getPublishStatus()) {
            queryWrapper.eq(MsgTypeDO::getPublishStatus, msgTypePageQuery.getPublishStatus());
        }

        if (null != msgTypePageQuery.getSms()) {
            queryWrapper.eq(MsgTypeDO::getSms, msgTypePageQuery.getSms());
        }

        if (null != msgTypePageQuery.getEmail()) {
            queryWrapper.eq(MsgTypeDO::getEmail, msgTypePageQuery.getEmail());
        }

        if (StringUtils.isNotBlank(msgTypePageQuery.getCode())) {
            queryWrapper.like(MsgTypeDO::getCode, msgTypePageQuery.getCode());
        }

        if (StringUtils.isNotBlank(msgTypePageQuery.getName())) {
            queryWrapper.like(MsgTypeDO::getName, msgTypePageQuery.getName());
        }

        Page<MsgTypeDO> page = msgTypeMapper.selectPage(new Page<>(msgTypePageQuery.getPageNum(), msgTypePageQuery.getPageSize()), queryWrapper);
        return BeanUtil.convertPage(page, MsgTypePageVO.class);
    }

    @Override
    public Boolean add(SmsTypeParam smsTypeParam) {
        Long id1 = getBean().checkName(smsTypeParam.getName());
        if (null != id1) {
            throw new BusinessException("当前消息类型名称已存在");
        }

        Long id2 = getBean().checkCode(smsTypeParam.getCode());
        if (null != id2) {
            throw new BusinessException("当前消息类型编码已存在");
        }
        MsgTypeDO msgTypeDO = BeanUtil.convertBean(smsTypeParam, MsgTypeDO.class);
        msgTypeDO.setCreateTime(LocalDateTime.now());
        msgTypeDO.setModifyTime(LocalDateTime.now());
        return msgTypeMapper.insert(msgTypeDO) > 0;
    }

    @CacheEvict(cacheName = RedisKeyConstant.MODULE + RedisKeyConstant.MSG_TYPE, key = "#smsTypeParam.id")
    @Override
    public Boolean modify(SmsTypeParam smsTypeParam) {
        Long id1 = getBean().checkName(smsTypeParam.getName());
        if (null != id1 && !id1.equals(smsTypeParam.getId())) {
            throw new BusinessException("当前消息类型名称已存在");
        }
        MsgTypeDO msgTypeDO = BeanUtil.convertBean(smsTypeParam, MsgTypeDO.class);
        msgTypeDO.setCode(null);
        msgTypeDO.setModifyTime(LocalDateTime.now());
        return msgTypeMapper.updateById(msgTypeDO) > 0;
    }

    @Override
    public MsgTypeVO view(Long id) {
        return BeanUtil.convertBean(getBean().queryById(id), MsgTypeVO.class);
    }

    @CacheQuery(cacheName = RedisKeyConstant.MODULE + RedisKeyConstant.MSG_TYPE, key = "#id", expires = RedisKeyConstant.MONTH)
    @Override
    public MsgTypeBO queryById(Long id) {
        MsgTypeDO msgTypeDO = msgTypeMapper.selectById(id);
        return BeanUtil.convertBean(msgTypeDO, MsgTypeBO.class);
    }

    @CacheEvict(cacheName = RedisKeyConstant.MODULE + RedisKeyConstant.MSG_TYPE, key = "#id")
    @Override
    public Boolean changeStatus(Long id, Integer status, Long userId) {
        MsgTypeDO msgTypeDO1 = msgTypeMapper.selectById(id);
        MsgTypeDO msgTypeDO = new MsgTypeDO();
        msgTypeDO.setId(id);
        msgTypeDO.setPublishStatus(status);
        msgTypeDO.setModifyBy(userId);
        msgTypeDO.setModifyTime(LocalDateTime.now());
        boolean b = msgTypeMapper.updateById(msgTypeDO) > 0;
        if (b) {
            redisUtils.del(RedisKeyConstant.MODULE + RedisKeyConstant.MSG_TYPE + msgTypeDO1.getCode());
        }
        return b;
    }

    @CacheEvict(cacheName = RedisKeyConstant.MODULE + RedisKeyConstant.MSG_TYPE, key = "#id")
    @Override
    public Boolean del(Long id) {
        MsgTypeDO msgTypeDO1 = msgTypeMapper.selectById(id);
        boolean b = msgTypeMapper.deleteById(id) > 0;
        if (b) {
            redisUtils.del(RedisKeyConstant.MODULE + RedisKeyConstant.MSG_TYPE + msgTypeDO1.getCode());
        }
        return b;
    }

    @Override
    public Long checkName(String name) {
        MsgTypeDO msgTypeDO = msgTypeMapper.selectOne(new LambdaQueryWrapper<>(MsgTypeDO.class).eq(MsgTypeDO::getName, name));
        if (null == msgTypeDO) {
            return null;
        }
        return msgTypeDO.getId();
    }

    @Override
    public Long checkCode(String code) {
        MsgTypeDO msgTypeDO = msgTypeMapper.selectOne(new LambdaQueryWrapper<>(MsgTypeDO.class).eq(MsgTypeDO::getCode, code));
        if (null == msgTypeDO) {
            return null;
        }
        return msgTypeDO.getId();
    }

    @Override
    public SendSmsParamBo querySmsParamByCode(String code, Integer tenantId) {
        MsgTypeBO msgTypeBO = SpringBeanUtil.getBean(IMsgTypeService.class).queryByCode(code);
        if (null == msgTypeBO) {
            return null;
        }
        MsgRelationBO msgRelationBO = smsRelationServiceImpl.queryById(tenantId, msgTypeBO.getId());
        if (null == msgRelationBO) {
            return null;
        }
        SmsConfigBO smsConfigBO = smsConfigServiceImpl.queryDefaultConfig();
        if (null == smsConfigBO) {
            return null;
        }
        SmsConfigSignBO smsConfigSignBO = smsConfigSignServiceImpl.queryById(msgRelationBO.getMsgSignId());
        if (null == smsConfigSignBO) {
            return null;
        }
        SmsTemplateBO smsTemplateBO = smsTemplateServiceImpl.queryById(msgRelationBO.getMsgTemplateId());
        if (null == smsTemplateBO) {
            return null;
        }
        SendSmsParamBo sendSmsParamBo = new SendSmsParamBo();
        sendSmsParamBo.setMsgTypeId(msgTypeBO.getId());
        sendSmsParamBo.setTenantId(tenantId);
        if(smsConfigBO.getSmsVendorCode().equalsIgnoreCase(SmsVendorEnum.SMS_ALI.getCode())) {
            sendSmsParamBo.setAccessKey(smsConfigBO.getSmsConfigByAli().getAccessKey());
            sendSmsParamBo.setAccessSecret(smsConfigBO.getSmsConfigByAli().getAccessSecret());
            sendSmsParamBo.setSecretKey(smsConfigBO.getSmsConfigByAli().getSecretKey());
        }
        sendSmsParamBo.setSignName(smsConfigSignBO.getSignName());
        sendSmsParamBo.setTemplateCode(smsTemplateBO.getTemplateCode());

        return sendSmsParamBo;
    }

    @CacheQuery(cacheName = RedisKeyConstant.MODULE + RedisKeyConstant.MSG_TYPE, key = "#code", expires = RedisKeyConstant.MONTH)
    @Override
    public MsgTypeBO queryByCode(String code) {
        MsgTypeDO msgTypeDO = msgTypeMapper.selectOne(new LambdaQueryWrapper<>(MsgTypeDO.class).eq(MsgTypeDO::getCode, code));
        return BeanUtil.convertBean(msgTypeDO, MsgTypeBO.class);
    }

    private IMsgTypeService getBean() {
        return SpringBeanUtil.getBean(IMsgTypeService.class);
    }
}
